﻿using Engine;
using Engine.Graphics;
using Game;
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace ApiToolkit
{
	#region Block
	public class BlocksDataEditor : FlatBlock //方块定义
	{
		public const int Index = 1000;

		public const string texturePath = @"Textures/BlocksDataEditor";//材质路径
		public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
		{
			BlocksManager.DrawFlatBlock(primitivesRenderer, value, size * 1f, ref matrix, m_texture, Color.White, isEmissive: true, environmentData);
		}
		public override void Initialize()
		{
			base.Initialize();

			m_texture = ContentManager.Get<Texture2D>(texturePath);
		}
		public Texture2D m_texture;
	}
	public class BlocksDataEditorBehavior : SubsystemBlockBehavior
	{
		public override int[] HandledBlocks => new int[] { 1000 };
		public override bool OnUse(Ray3 ray, ComponentMiner miner)
		{

			object obj = miner.Raycast(ray, RaycastMode.Digging);
			if (obj is TerrainRaycastResult)
			{
				var raycast = (TerrainRaycastResult)obj;
				var blockID = Terrain.ExtractContents(raycast.Value);
				DialogsManager.ShowDialog(miner.ComponentPlayer.GuiWidget, new BlocksDataEdit(blockID));
				return true;
			}
			DialogsManager.ShowDialog(miner.ComponentPlayer.GuiWidget, new BlocksDataEdit());

			return true;

		}
	}

	#endregion
	public class BlocksDataEdit : Dialog
	{

		#region MemberWidgets
		TextBoxWidget BlockIDTextBox;

		LabelWidget BlockNameLabel;

		BlockIconWidget BlockIcon;

		ListPanelWidget BlockDataList;

		BevelledButtonWidget CloseButton;

		CanvasWidget EditorCanvas;

		LabelWidget PropertyInfoLabel;

		LabelWidget DescriptionLabel;

		ButtonWidget ImportButton;
		#endregion

		#region Construct
		public BlocksDataEdit(int blockID) : this()
		{

			BlockIDTextBox.Text = blockID.ToString();
			UpdateBlockControls(blockID);
		}
		public BlocksDataEdit()
		{
			try
			{
				XElement dialogNode = ContentManager.Get<XElement>("Dialogs/BlocksDataEdit");
				LoadContents(this, dialogNode);
				InitControls();
			}
			catch (Exception ex)
			{
				Log.Error(ex);
				throw;
			}
		}

		private void InitControls()
		{
			ImportButton = Children.Find<ButtonWidget>("ImportButton");

			BlockIDTextBox = Children.Find<TextBoxWidget>("BlockIDTextBox");

			BlockNameLabel = Children.Find<LabelWidget>("BlockNameLabel");

			BlockIcon = Children.Find<BlockIconWidget>("BlockIcon");

			EditorCanvas = Children.Find<CanvasWidget>("EditorCanvas");

			BlockDataList = Children.Find<ListPanelWidget>("BlockDataList");

			BlockDataList.ItemClicked = delegate (object item)
			{
				EditorCanvas.Children.Clear();
				if (!BlockIDTextBox.Text.TryConvertToInt32(out int res))
				{
					var message = new MessageDialog("无法编辑属性", "请填写要编辑的方块id", LanguageControl.Ok, null, null);
					DialogsManager.ShowDialog(ParentWidget, message);
					return;
				}
				var blockData = (BlockProperty)item;
				//获取点击的方块属性

				var status = blockData.Update(latestBlockID);
				//设置方块，并获取方块属性的状态
				PropertyInfoLabel.Text = blockData.BindingProperty;
				DescriptionLabel.Text = blockData.Description;


				if (status == BlockProperty.PropertyStatus.EditorNotFound)
				{
					var message = new MessageDialog("无法编辑属性", "暂未支持该类型的编辑器", LanguageControl.Ok, null, null);
					DialogsManager.ShowDialog(ParentWidget, message);
					return;
				}

				EditorCanvas.Children.Add(blockData.Editor);
			};

			var blocksData = ContentManager.Get<string>("BlocksData");
			var firstLine = blocksData.Substring(0, blocksData.IndexOf('\n') - 1);
			foreach (var propName in firstLine.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
			//以';' 作为分隔符，遍历BlockData.txt 的第一行
			{
				if (propName != "Class Name")
					BlockDataList.AddItem(new BlockProperty(propName, ParentWidget));
			}

			BlockDataList.ItemWidgetFactory = delegate (object item)
			{
				var blockData = (BlockProperty)item;
				return new LabelWidget() { Text = blockData.PropertyDisplayName };
			};

			CloseButton = Children.Find<BevelledButtonWidget>("CloseButton");

			PropertyInfoLabel = Children.Find<LabelWidget>("PropertyInfoLabel");

			DescriptionLabel = Children.Find<LabelWidget>("DescriptionLabel");
		}
		#endregion
		int latestBlockID;

		//当选择的方块ID发生变化时调用
		public void UpdateBlockControls(int blockID)
		{
			var block = BlocksManager.Blocks[blockID];

			if (LanguageControl.TryGetBlock(block.GetType().Name + ":0", "DisplayName", out var result))
			{
				//更新方块名称
				BlockNameLabel.Text = result;
			}

			BlockIcon.Contents = blockID;
			//更新方块图标

			EditorCanvas.Children.Clear();
		}
		public override void Update()
		{
			if (base.Input.Cancel || CloseButton.IsClicked)
			{
				Close();
				return;
			}

			if (BlockIDTextBox.Text.TryConvertToInt32(out int result))
			{
				int blockID = result;
				if (!(blockID > 0 && blockID < 1024))
				{
					BlockIcon.Contents = 0;
					EditorCanvas.Children.Clear();
					return;
				}
				if (latestBlockID != blockID)
				{
					latestBlockID = blockID;
					UpdateBlockControls(latestBlockID);
				}
			}
			else
			{
				BlockIDTextBox.Text = new string((from i in BlockIDTextBox.Text
												  where "0123456789".Contains_(i)
												  select i).ToArray<char>());
				//保留TextBox内的数字元素
				BlockIcon.Contents = 0;
				EditorCanvas.Children.Clear();
				return;
			}

			if (ImportButton.IsClicked)
			{
				try
				{
					var csv = BlockToCsv(latestBlockID);
					ClipboardManager.ClipboardString += csv;
					var message = new MessageDialog("导出成功", "已复制至剪贴板", LanguageControl.Ok, null, null);
					DialogsManager.ShowDialog(ParentWidget, message);
				}
				catch (Exception ex)
				{
					Log.Error(ex.ToString());
				}
			}
		}
		private string BlockToCsv(int content)
		{
			string result = string.Empty;

			var blocksData = ContentManager.Get<string>("BlocksData");
			var block = BlocksManager.Blocks[content];
			var firstLine = blocksData.Substring(0, blocksData.IndexOf('\n') - 1);
			foreach (var propName in firstLine.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
			//以';' 作为分隔符，遍历BlockData.txt 的第一行
			{
				if (propName != "Class Name")
				{
					string value;
					PropertyEditor_Common editor = new(content, propName);

					if (editor.TargetPropertyValue == null)
					{
						value = string.Empty;
					}
					else
					{
						var tmp = editor.TargetPropertyValue;
						if (tmp is Vector3)
						{
							var vect = (Vector3)tmp;
							value = $"{vect.X}, {vect.Y}, {vect.Z}";
						}
						else
						{
							value = tmp.ToString();
						}
					}

					result += ";" + value;
				}
				else
				{
					result += block.GetType().Name;
				}
			}
			
			return result;
		}

		private void Close()
		{
			DialogsManager.HideDialog(this);
		}
	}
}